package com.stt.experiment.trynetty.util;

/**
 * unicode码转换工具类
 * User: hlf
 * email: flyfeel1987@163.com
 * Date: 13-11-18
 * Time: 上午11:41
 */
public class UnicodeUtils {

        
        private static final char[] hexDigit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',

                'B', 'C', 'D', 'E', 'F' };


        private static char toHex(int nibble) {

            return hexDigit[(nibble & 0xF)];

        }


        /**

         * 将字符串编码成 Unicode 形式的字符串.

         * Converts unicodes to encoded \\uxxxx and escapes

         * special characters with a preceding slash

         *

         * @param theString

         *        待转换成Unicode编码的字符串。

         * @param escapeSpace

         *        是否忽略空格，为true时在空格后面是否加个反斜杠。

         * @return 返回转换后Unicode编码的字符串。

         */

        public static String toEncodedUnicode(String theString, boolean escapeSpace) {

            int len = theString.length();

            int bufLen = len * 2;

            if (bufLen < 0) {

                bufLen = Integer.MAX_VALUE;

            }

            StringBuffer outBuffer = new StringBuffer(bufLen);




            for (int x = 0; x < len; x++) {

                char aChar = theString.charAt(x);

                if ((aChar > 61) && (aChar < 127)) {

                    if (aChar == '\\') {

                        outBuffer.append('\\');

                        outBuffer.append('\\');

                        continue;

                    }

                    outBuffer.append(aChar);

                    continue;

                }



                switch (aChar) {

                    case ' ':

                        if (x == 0 || escapeSpace) outBuffer.append('\\');

                        outBuffer.append(' ');

                        break;

                    case '\t':

                        outBuffer.append('\\');

                        outBuffer.append('t');

                        break;

                    case '\n':

                        outBuffer.append('\\');

                        outBuffer.append('n');

                        break;

                    case '\r':

                        outBuffer.append('\\');

                        outBuffer.append('r');

                        break;

                    case '\f':

                        outBuffer.append('\\');

                        outBuffer.append('f');

                        break;

                    case '=': // Fall through

                    case ':': // Fall through

                    case '#': // Fall through

                    case '!':

                        //outBuffer.append('\\');

                        outBuffer.append(aChar);

                        break;

                    default:

                        if ((aChar < 0x0020) || (aChar > 0x007e)) {

                            // 每个unicode有16位，每四位对应的16进制从高位保存到低位

                            outBuffer.append('\\');

                            outBuffer.append('u');

                            outBuffer.append(toHex((aChar >> 12) & 0xF));

                            outBuffer.append(toHex((aChar >> 8) & 0xF));

                            outBuffer.append(toHex((aChar >> 4) & 0xF));

                            outBuffer.append(toHex(aChar & 0xF));

                        } else {

                            outBuffer.append(aChar);

                        }

                }

            }

            return outBuffer.toString();

        }




        /**

         * 从 Unicode 形式的字符串转换成对应的编码的特殊字符串。

         * Converts encoded \\uxxxx to unicode chars

         * and changes special saved chars to their original forms

         *

         * @param in

         *        Unicode编码的字符数组。

         * @param off

         *        转换的起始偏移量。

         * @param len

         *        转换的字符长度。

         * @return 完成转换，返回编码前的特殊字符串。

         */

        public static String fromEncodedUnicode(char[] in, int off, int len) {

            char aChar;

            char[] out = new char[len]; // 只短不长

            int outLen = 0;

            int end = off + len;




            while (off < end) {

                aChar = in[off++];

                if (aChar == '\\') {

                    aChar = in[off++];

                    if (aChar == 'u') {

                        // Read the xxxx

                        int value = 0;

                        for (int i = 0; i < 4; i++) {

                            aChar = in[off++];

                            switch (aChar) {

                                case '0':

                                case '1':

                                case '2':

                                case '3':

                                case '4':

                                case '5':

                                case '6':

                                case '7':

                                case '8':

                                case '9':

                                    value = (value << 4) + aChar - '0';

                                    break;

                                case 'a':

                                case 'b':

                                case 'c':

                                case 'd':

                                case 'e':

                                case 'f':

                                    value = (value << 4) + 10 + aChar - 'a';

                                    break;

                                case 'A':

                                case 'B':

                                case 'C':

                                case 'D':

                                case 'E':

                                case 'F':

                                    value = (value << 4) + 10 + aChar - 'A';

                                    break;

                                default:

                                    throw new IllegalArgumentException("Malformed \\uxxxx encoding.");

                            }

                        }

                        out[outLen++] = (char) value;

                    } else {

                        if (aChar == 't') {

                            aChar = '\t';

                        } else if (aChar == 'r') {

                            aChar = '\r';

                        } else if (aChar == 'n') {

                            aChar = '\n';

                        } else if (aChar == 'f') {

                            aChar = '\f';

                        }

                        out[outLen++] = aChar;

                    }

                } else {

                    out[outLen++] = aChar;

                }

            }

            return new String(out, 0, outLen);

        }

}
